package com.yoda.mall.admin.service;

import com.yoda.common.Status;
import com.yoda.common.constant.RC;
import com.yoda.mall.admin.intercepter.ThreadContext;
import com.yoda.common.utils.Utils;
import com.yoda.mall.admin.auth.JwtUtils;
import com.yoda.mall.api.AdminApi;
import com.yoda.mall.api.AdminLoginLogApi;
import com.yoda.mall.api.RoleMenuRelationApi;
import com.yoda.mall.model.dto.LoginDto;
import com.yoda.mall.model.entity.ums.Admin;
import com.yoda.mall.model.entity.ums.AdminLoginLog;
import com.yoda.mall.model.entity.ums.Role;
import com.yoda.mall.model.vo.LoginVo;
import com.yoda.mall.model.vo.ManagerInfoVo;
import com.yoda.mall.model.vo.PageResult;
import com.yoda.mall.model.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author shawn
 * @date 2022年 12月 15日 22:11
 */
@Slf4j
@Service
public class AdminService {
    @DubboReference
    private AdminApi adminApi;

    @DubboReference
    private AdminLoginLogApi adminLoginLogApi;

    @DubboReference
    private RoleMenuRelationApi roleMenuRelationApi;


    @Resource
    private RedisTemplate<String,String> redisTemplate;

    public R login(HttpServletRequest request , LoginDto dto) {
        //获取同名管理员用户
      Admin admin = adminApi.selectByName(dto.getUsername());
        String pass = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8));
        System.out.println(pass);
      //如果用户不存在,获取密码比对为错误,响应失败
        if (Objects.isNull(admin)|| !DigestUtils.md5DigestAsHex(dto.getPassword().getBytes(StandardCharsets.UTF_8)).equals(admin.getPassword())){
            return R.error("账户名错误或用户不存在", Status.UN_AUTHORIZED.getCode());
        }
        //判断是否禁用
        if (admin.getStatus()==0){
            return R.error("该账号已被禁用", Status.FORBIDDEN.getCode());
        }
        //用户存在,调用用户信息生成token
        Map<String,Object> params = new HashMap<>();
        String ip = Utils.getRealIp(request);
        //解析归属地
        String address = Utils.getAddress(ip);
        //解析浏览器类型
        String browserName = Utils.browserName(request);
        params.put("id",admin.getId());
        params.put("username",admin.getUsername());
        params.put("ip",ip);
        //获取用户登录ip
        String token = JwtUtils.getToken(params);
        LoginVo loginVo = new LoginVo();
        loginVo.setTokenHead(RC.TOKEN_HEAD);
        loginVo.setToken(token);
        //保存用户登录日志
        AdminLoginLog log = new AdminLoginLog();
        log.setAdminId(admin.getId());
        log.setAddress(ip);
        log.setAddress(address);
        log.setUserAgent(browserName);
        //保存日志
        adminLoginLogApi.save(log);
        return R.success(loginVo);
    }

    /**
     * 得到管理员信息
     *
     * @return {@link ManagerInfoVo}
     */
    public ManagerInfoVo getManagerInfo() {
        Long adminId = ThreadContext.getAdminId();
        //查询管理员信息
        return adminApi.getAdminInfo(adminId);
    }

    public PageResult<Admin> selectByPage(String keyword, Integer page, Integer pageSize) {
       return adminApi.selectByPage(page,pageSize,keyword);
    }

    public Admin registerAccount(Admin admin) {
        String password = DigestUtils.md5DigestAsHex(admin.getPassword().getBytes(StandardCharsets.UTF_8));
        admin.setPassword(password);
        return adminApi.registerAccount(admin);
    }

    public Integer assigningRoles(Long adminId, List<Long> roleIds) {
        return adminApi.assigningRoles(adminId,roleIds);
    }

    public Integer updateAccount(Admin admin) {
        return adminApi.updateAccount(admin);
    }

    public Integer deleteAccountById(Long id) {
        redisTemplate.opsForSet().add(RC.BLACK_LIST_ID,id.toString());
        return adminApi.deleteAccountById(id);
    }

    public List<Role> getSpecifyRole(Long adminId) {
        return adminApi.getSpecifyRole(adminId);
    }

    public Integer updateAccountStatus(Long id, Integer status) {
        //账号禁用逻辑
        if (status==0){
            redisTemplate.opsForSet().add(RC.BLACK_LIST_ID,id.toString());
        }else {
            Boolean isMember = redisTemplate.opsForSet().isMember(RC.BLACK_LIST_ID, id.toString());
            if (Boolean.TRUE.equals(isMember)){
                redisTemplate.opsForSet().remove(RC.BLACK_LIST_ID,id.toString());
            }
        }
        Admin admin = new Admin();
        admin.setId(id);
        admin.setStatus(status);
        return adminApi.updateAccount(admin);
    }
}
